from django.contrib.auth.models import AnonymousUser
from django.core.exceptions     import ObjectDoesNotExist
from django.db.models           import signals
from django.db.utils            import DatabaseError
from sitepal.sitebase.models    import Property

class Properties(object):
    def __init__(self):
        self._properties     = dict()
        self._properties_len = None

    def _get_property(self,name):
        props = self._properties
        if name in props:
            return props[name]
        else:
            try:
                value       = Property.objects.get(name__exact=name)
                props[name] = value
                return value
            except DatabaseError:
                return None
            except ObjectDoesNotExist:
                raise AttributeError,"Property '{0}' does not exist".format(name)
    
    def get_value(self,name,default=u'',user=None,admin=False):
        prop = self._get_property(name)
        if not prop:
            return default
        if admin:
            return prop.get_value(default=default)
        user = user or AnonymousUser()
        if user.is_admin or user.has_perm('sitebase.read_property',prop):
            return prop.get_value(default=default)
        return default
    get = get_value

    def set_value(self,name,value,user=None,admin=False):
        prop = self._get_property(name)
        user = user or AnonymousUser()
        if admin or user.has_perm('sitebase.change_property',prop):
            prop.set_value(value)
            prop.save()
        else:
            raise AttributeError,"Property '{0}' does not exist".format(name)

    def __len__(self):
        if self._properties_len is None:
            self._properties_len = Property.objects.count()
        return self._properties_len

    def __contains__(self,key):
        if key in self._properties:
            return True
        return Property.objects.filter(name__exact=key).exists()

    def post_save_callback(self,sender,instance,created,**kwargs):
        self._properties[instance.name] = instance
        
properties = Properties()
signals.post_save.connect(properties.post_save_callback,sender=Property)
